package me.kuye.jkuye.render;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

public class FreeMarkerRender extends Render {

	private static final String encoding = getEncoding();

	private static final String contentType = "text/html;charset=" + encoding;

	private static final Configuration config = new Configuration();

	public FreeMarkerRender(String view) {
		this.view = view;
	}

	public static void init(ServletContext servletContext, Locale locale, int freemarkerTemplateUpdateDelay) {
		config.setServletContextForTemplateLoading(servletContext, "/");

		if (isDevMode()) {
			config.setTemplateUpdateDelay(0);
		} else {
			config.setTemplateUpdateDelay(freemarkerTemplateUpdateDelay);
		}

		config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

		config.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);

		config.setDefaultEncoding(encoding);

		config.setOutputEncoding(encoding);

		config.setLocale(locale);

		config.setLocalizedLookup(false);

		config.setNumberFormat("#0.#####");
		config.setDateFormat("yyyy-MM-dd");
		config.setTimeFormat("HH:mm:ss");
		config.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void render() {
		response.setContentType(contentType);
		
		Map map = new HashMap();
		for (Enumeration<String> attrs = request.getAttributeNames(); attrs.hasMoreElements();) {
			String attrName = attrs.nextElement();
			map.put(attrName, request.getAttribute(attrName));
		}

		PrintWriter printWriter = null;
		try {
			Template template = config.getTemplate(view);
			printWriter = response.getWriter();
			template.process(map, printWriter);
		} catch (Exception e) {
			throw new RenderException(e);
		} finally {
			if (printWriter != null) {
				printWriter.close();
			}
		}

	}

	public static void setProperties(Properties properties) {
		try {
			FreeMarkerRender.getConfiguration().setSettings(properties);
		} catch (TemplateException e) {
			throw new RuntimeException(e);
		}
	}

	public static void setProperties(String propertiesKey, String propertiesValue) {
		try {
			FreeMarkerRender.getConfiguration().setSetting(propertiesKey, propertiesValue);
		} catch (TemplateException e) {
			throw new RuntimeException(e);
		}
	}

	public static String getEncoding() {
		return encoding;
	}

	public static String getContenttype() {
		return contentType;
	}

	public static Configuration getConfiguration() {
		return config;
	}

}
